#include "Acceptor.h"
#include "Logger.h"

#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>

static int createNonBlocking()
{
  int sockfd = ::socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, IPPROTO_TCP);  
  if (sockfd < 0) {
    LOG_FATAL("create socket failed");
  }
  return sockfd;
}

Acceptor::Acceptor(EventLoop *loop, const InetAddress &listenAddr, bool reusePort)
  : m_loop(loop)
  , m_acceptSocket(createNonBlocking())
  , m_listening(false)
  , m_acceptChannel(m_loop, m_acceptSocket.fd())
{
  m_acceptSocket.setReuseAddr(true);
  m_acceptSocket.setReusePort(true);
  m_acceptSocket.bindAddress(listenAddr);
  // Acceptor 如果有新用户链接要执行一个回调 connfd => channel => subloop
  m_acceptChannel.setReadCallback(std::bind(&Acceptor::handleRead, this));
}

void Acceptor::handleRead()
{
  InetAddress peerAddr;
  int connfd = m_acceptSocket.accept(&peerAddr);
  if (connfd >= 0) {
    if (m_newConnectionCallback) {
      m_newConnectionCallback(connfd, peerAddr);
    } else {
      ::close(connfd);
    }
  } else {
    LOG_ERROR("accept failed");
  }
}

Acceptor::~Acceptor()
{
  m_acceptChannel.disableAll();
  m_acceptChannel.remove();
}

void Acceptor::listen()
{
  m_listening = true;
  m_acceptSocket.listen();
  m_acceptChannel.enableReading();
}